package com.example.linuxweb.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import com.example.linuxweb.model.*;
import org.springframework.stereotype.Service;

@Service
public class CommandService {
    public Command executeCommand(String input, TerminalSession session) {
        // ===== 调试日志 =====
        System.out.println("[DEBUG] Executing command: " + input);
        System.out.println("[DEBUG] Current directory: " +
                session.getFileSystem().getCurrentDirectory().getPath());
        // ==================

        String[] parts = input.split(" ");
        String command = parts[0];
        String[] args = Arrays.copyOfRange(parts, 1, parts.length);

        FileSystem fs = session.getFileSystem();
        String output;
        String currentDir = fs.getCurrentDirectory().getPath();

        switch (command) {
            case "ls":
                output = executeLs(fs.getCurrentDirectory(), args);
                break;
            case "cd":
                output = executeCd(fs, args);
                currentDir = fs.getCurrentDirectory().getPath();
                break;
            case "pwd":
                output = currentDir;
                break;
            case "mkdir":
                output = executeMkdir(fs.getCurrentDirectory(), args);
                break;
            case "touch":
                output = executeTouch(fs.getCurrentDirectory(), args);
                break;
            case "cat":
                output = executeCat(fs.getCurrentDirectory(), args);
                break;
            case "echo":
                output = executeEcho(fs.getCurrentDirectory(), args);
                break;
            case "rm":
                output = executeRm(fs.getCurrentDirectory(), args);
                break;
            case "help":
                output = getHelpText();
                break;
            case "clear":
                session.getCommandHistory().clear();
                output = "";
                break;
            default:
                output = "Command not found: " + command + "\nType 'help' for available commands";
        }

        Command cmd = new Command(input, output, currentDir);
        session.addCommandToHistory(cmd);
        return cmd;
    }

    private String executeLs(FileNode dir, String[] args) {
        boolean showDetails = false;
        for (String arg : args) {
            if (arg.equals("-l")) {
                showDetails = true;
            }
        }

        StringBuilder sb = new StringBuilder();
        for (FileNode child : dir.getChildren()) {
            if (showDetails) {
                sb.append(child.isDirectory() ? "d" : "-")
                        .append("rw-r--r-- 1 user user ")
                        .append(child.isDirectory() ? "0" : child.getContent().length())
                        .append(" ")
                        .append(child.getName())
                        .append("\n");
            } else {
                sb.append(child.getName()).append("  ");
            }
        }
        return sb.toString().trim();
    }

    private String executeCd(FileSystem fs, String[] args) {
        if (args.length == 0) {
            fs.setCurrentDirectory(fs.getRoot().findChild("home").findChild("user"));
            return "";
        }

        String path = args[0];
        FileNode current = fs.getCurrentDirectory();

        if (path.equals("..")) {
            if (current.getParent() != null) {
                fs.setCurrentDirectory(current.getParent());
            }
            return "";
        } else if (path.equals("/")) {
            fs.setCurrentDirectory(fs.getRoot());
            return "";
        } else if (path.startsWith("/")) {
            // Absolute path
            FileNode target = navigateToPath(fs.getRoot(), path.substring(1));
            if (target != null && target.isDirectory()) {
                fs.setCurrentDirectory(target);
                return "";
            } else {
                return "cd: " + path + ": No such directory";
            }
        } else {
            // Relative path
            FileNode target = navigateToPath(current, path);
            if (target != null && target.isDirectory()) {
                fs.setCurrentDirectory(target);
                return "";
            } else {
                return "cd: " + path + ": No such directory";
            }
        }
    }

    private FileNode navigateToPath(FileNode start, String path) {
        FileNode current = start;
        String[] parts = path.split("/");

        for (String part : parts) {
            if (part.isEmpty()) continue;

            if (part.equals("..")) {
                if (current.getParent() != null) {
                    current = current.getParent();
                }
            } else {
                FileNode child = current.findChild(part);
                if (child == null) {
                    return null;
                }
                current = child;
            }
        }
        return current;
    }

    private String executeMkdir(FileNode dir, String[] args) {
        if (args.length == 0) {
            return "mkdir: missing operand";
        }

        for (String name : args) {
            if (dir.findChild(name) != null) {
                return "mkdir: cannot create directory '" + name + "': File exists";
            }
            dir.addChild(new FileNode(name, true));
        }
        return "";
    }

    private String executeTouch(FileNode dir, String[] args) {
        if (args.length == 0) {
            return "touch: missing file operand";
        }

        for (String name : args) {
            if (dir.findChild(name) == null) {
                dir.addChild(new FileNode(name, false));
            }
        }
        return "";
    }

    private String executeCat(FileNode dir, String[] args) {
        if (args.length == 0) {
            return "cat: missing file operand";
        }

        StringBuilder sb = new StringBuilder();
        for (String name : args) {
            FileNode file = dir.findChild(name);
            if (file == null) {
                sb.append("cat: ").append(name).append(": No such file\n");
            } else if (file.isDirectory()) {
                sb.append("cat: ").append(name).append(": Is a directory\n");
            } else {
                sb.append(file.getContent()).append("\n");
            }
        }
        return sb.toString().trim();
    }

    private String executeEcho(FileNode dir, String[] args) {
        if (args.length == 0) {
            return "";
        }

        // Simple echo implementation - just join the arguments
        return String.join(" ", args);
    }

    private String executeRm(FileNode dir, String[] args) {
        if (args.length == 0) {
            return "rm: missing operand";
        }

        boolean recursive = false;
        List<String> files = new ArrayList<>();

        for (String arg : args) {
            if (arg.equals("-r")) {
                recursive = true;
            } else {
                files.add(arg);
            }
        }

        StringBuilder sb = new StringBuilder();
        for (String name : files) {
            FileNode node = dir.findChild(name);
            if (node == null) {
                sb.append("rm: cannot remove '").append(name).append("': No such file or directory\n");
                continue;
            }

            if (node.isDirectory() && node.getChildren().size() > 0 && !recursive) {
                sb.append("rm: cannot remove '").append(name).append("': Directory not empty\n");
            } else {
                dir.getChildren().remove(node);
            }
        }
        return sb.toString().trim();
    }

    private String getHelpText() {
        return "Available commands:\n" +
                "ls [directory]      - List directory contents\n" +
                "cd [directory]      - Change directory\n" +
                "pwd                 - Print working directory\n" +
                "mkdir <dir>         - Create directory\n" +
                "touch <file>        - Create file\n" +
                "cat <file>          - Display file contents\n" +
                "echo <text>         - Display text\n" +
                "rm <file/dir>       - Remove file or directory (use -r for directories)\n" +
                "clear               - Clear terminal\n" +
                "help                - Show this help message";
    }
}
